在 kintone 的清單畫面做 JavaScript 客製化時,應該不少人都遇過一個有點惱人的狀況:
明明在 app.record.index.show 裡面已經把清單樣式處理好了,結果使用者一進行行內編輯,按下「儲存」或「取消」之後,剛剛套好的樣式就不見了。
像是常見的條件式格式、進度條、欄位背景色、文字顏色,或是自己塞進去的 DOM,都可能遇到這種情況。
這篇要介紹的是 2026 年 3 月版更新後新增的事件:
app.record.index.edit.finish
有了這個事件之後,就不需要再用 setTimeout 硬等 DOM 更新,也不用為了重新套樣式而強制重新整理頁面。
假設我們在清單畫面中,依照「優先度」欄位的值套用不同背景色。
例如:
這類處理通常會寫在 app.record.index.show 裡面,清單畫面顯示後再用 JavaScript 去調整欄位元素的樣式。但如果使用者在清單畫面直接編輯某一筆資料,也就是使用 kintone 的行內編輯功能,然後按下「取消」,就會發現剛剛編輯的那一列樣式消失了。
原因是:kintone 在結束行內編輯時,會重新建構該列的 DOM。
也就是說,我們原本用 JavaScript 加上去的背景色、文字顏色或 DOM 修改,會在 kintone 重建那一列時被清掉。這也是為什麼只靠 app.record.index.show 不夠,因為清單畫面不是重新顯示整頁,而是只有編輯過的那列被重新處理。
app.record.index.edit.finish這次的主角就是:
app.record.index.edit.finish
這個事件會在清單畫面的行內編輯結束後觸發,不管使用者是按「儲存」還是「取消」,只要回到表格顯示狀態,就會執行這個事件。
更重要的是,它是在 DOM 重新建構完成後才觸發。
所以我們可以很單純地把「重新套用樣式」的邏輯放在這個事件裡,不需要再寫:
setTimeout(() => {
// 重新套樣式
}, 500);
也不需要靠 event.url 去強制重新整理頁面。
以前如果只處理「儲存成功後樣式消失」的情境,可能會用 app.record.index.edit.submit.success 搭配 setTimeout。但這個做法有兩個問題:
submit.success 根本不會觸發所以如果要處理的是「回到清單顯示後,把畫面樣式補回來」,finish 事件會更適合。
app.record.index.edit.finish 的詳細說明,可以參考 Cybozu Developer Network 文件:記錄清單頁面內嵌編輯結束時的事件
這次範例只需要一個簡單欄位。
| 欄位名稱 | 欄位類型 | 欄位代碼 |
|---|---|---|
| 優先度 | 下拉式選單 | priority |
下拉式選單的選項設定為:
高
中
低
接著我們會依照不同的優先度,套用不同的背景色與文字顏色。
建立一個 JavaScript 檔案,並從 kintone App 設定中的「JavaScript / CSS 自訂」加入。
(() => {
'use strict';
// 依照優先度欄位的值,套用不同的條件式樣式
const applyConditionalFormatting = () => {
const elements = kintone.app.getFieldElements('priority');
if (!elements) {
return;
}
elements.forEach((el) => {
const priority = el.textContent.trim();
switch (priority) {
case '高':
el.style.backgroundColor = '#ffcccc';
el.style.color = '#cc0000';
break;
case '中':
el.style.backgroundColor = '#ffffcc';
el.style.color = '#cc8800';
break;
case '低':
el.style.backgroundColor = '#ccffcc';
el.style.color = '#008800';
break;
default:
break;
}
});
};
// 清單畫面顯示時,先套用一次條件式樣式
kintone.events.on('app.record.index.show', (event) => {
applyConditionalFormatting();
return event;
});
// 行內編輯結束後,再重新套用一次條件式樣式
kintone.events.on('app.record.index.edit.finish', (event) => {
applyConditionalFormatting();
return event;
});
})();
這段程式的重點是把樣式處理集中在 applyConditionalFormatting() 這個函式裡。
這樣做的好處是,清單畫面第一次顯示時可以呼叫一次,行內編輯結束後也可以再呼叫一次。
kintone.events.on('app.record.index.show', (event) => {
applyConditionalFormatting();
return event;
});
這段負責處理清單畫面初次顯示時的樣式。
而下面這段:
kintone.events.on('app.record.index.edit.finish', (event) => {
applyConditionalFormatting();
return event;
});
則負責在使用者結束行內編輯後,把樣式補回來。
因為 finish 事件是在表格顯示回來後觸發,所以這裡可以直接重新取得欄位元素並套用樣式,不需要刻意等待 DOM 更新。
另外,finish 事件不只會在儲存後觸發,取消時也會觸發。這正好解決了以前 submit.success 無法處理取消操作的問題。
不過要注意一點:finish 事件本身不會告訴你使用者剛剛是按「儲存」還是「取消」。
所以它適合用在「不需要判斷儲存或取消,只要畫面回到清單狀態就要執行」的處理,例如:
如果你的邏輯是「只有儲存成功後才要做」,那就不是 finish 的工作了。
finish 和 submit.success 要怎麼分?這兩個事件名稱很像,而且都跟清單畫面的行內編輯有關,所以很容易搞混。
簡單整理如下:
app.record.index.edit.submit.success |
app.record.index.edit.finish |
|
|---|---|---|
| 觸發時機 | 儲存成功後 | 儲存或取消後,回到表格顯示時 |
| 取消時是否觸發 | 不會 | 會 |
| 適合用途 | 儲存成功後的資料處理 | 畫面樣式或 DOM 的重新套用 |
| 典型情境 | 呼叫外部 API、更新其他 App、導頁 | 重新套用條件式格式、進度條、背景色 |
如果使用者按下「儲存」,兩個事件都會觸發,順序是:
app.record.index.edit.submit.success
→ app.record.index.edit.finish
所以可以這樣理解:
submit.success 是給「資料已經成功儲存」這件事使用的。finish 是給「畫面已經回到清單表格狀態」這件事使用的。
例如你要在儲存成功後,把資料送到其他系統,或是同步更新另一個 App,那應該使用 submit.success。
但如果你只是要把清單畫面的樣式補回來,像這次的條件式格式,那就應該使用 finish。
app.record.index.edit.submit.success 的詳細說明,可以參考 Cybozu Developer Network 文件:記錄清單頁面內嵌編輯成功時的事件
這次介紹的 app.record.index.edit.finish,主要解決的是清單畫面行內編輯後,因為 DOM 被重新建構,導致原本 JavaScript 客製化樣式消失的問題。
以前可能會用 setTimeout 等待畫面更新,或是透過重新整理頁面來處理,但這些做法都比較繞,也不一定能處理取消操作。
現在只要把畫面樣式的處理整理成函式,然後同時在:
app.record.index.show
以及
app.record.index.edit.finish
兩個事件中呼叫,就可以讓清單畫面的客製化在初次顯示與行內編輯結束後都維持一致。
如果你的 App 很常使用清單畫面的行內編輯,又有做條件式格式、進度條或其他 DOM 客製化,那這個事件會非常實用。